package com.hyt.it.ogt.pj.service.impl;

import java.math.BigDecimal;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hyt.core.base.BaseServiceImpl;
import com.hyt.it.ogt.pj.enums.CommonEnums;
import com.hyt.it.ogt.pj.mapper.ExamExpertMapper;
import com.hyt.it.ogt.pj.mapper.PieceScoreLogMapper;
import com.hyt.it.ogt.pj.mapper.PieceScoreMapper;
import com.hyt.it.ogt.pj.mapper.SubjectScoreMapper;
import com.hyt.it.ogt.pj.mapper.TaskMapper;
import com.hyt.it.ogt.pj.model.entity.ExamExpert;
import com.hyt.it.ogt.pj.model.entity.PieceScore;
import com.hyt.it.ogt.pj.model.entity.PieceScoreLog;
import com.hyt.it.ogt.pj.model.entity.SubjectScore;
import com.hyt.it.ogt.pj.model.entity.Task;
import com.hyt.it.ogt.pj.model.vo.CommentRecordVo;
import com.hyt.it.ogt.pj.model.vo.OptionItemVo;
import com.hyt.it.ogt.pj.model.vo.PipceScoreVo;
import com.hyt.it.ogt.pj.service.IPieceScoreService;

/**
 * <p>
 * 评卷块分数表 服务实现类
 * </p>
 *
 * @author qiaozj
 * @since 2020-07-09
 */
@Service
public class PieceScoreServiceImpl extends BaseServiceImpl<PieceScoreMapper, PieceScore> implements IPieceScoreService {

    @Autowired
    private PieceScoreMapper pieceScoreMapper;

	@Autowired
	private TaskMapper taskMapper;

	@Autowired
	private ExamExpertMapper examExpertMapper;

	@Autowired
	private SubjectScoreMapper subjectScoreMapper;

	@Autowired
	private PieceScoreLogMapper pieceScoreLogMapper;

    @Override
    public void deleteStuScoreBySubjectIdAndPieceIdAndEncodeId(String subjectId, String pieceId, String encodeId) {
        pieceScoreMapper.deleteStuScoreBySubjectIdAndPieceIdAndEncodeId(subjectId, pieceId, encodeId);
    }

	@Override
	public void deleteStuScoreBySubjectIdAndPieceIdAndEncodeIdAndUserid(String subjectId, String pieceId, String encodeId, String userId) {
		pieceScoreMapper.deleteStuScoreBySubjectIdAndPieceIdAndEncodeIdAndUserid(subjectId, pieceId, encodeId,userId);
	}

	@Override
	public PieceScore selectPieceScore(String subjectId, String pieceId, String encodeId) {
		List<PieceScore> pieceScoreList = this.lambdaQuery()
				.eq(PieceScore::getSubjectId, subjectId)
				.eq(PieceScore::getEncodeId, encodeId)
				.eq(pieceId != null, PieceScore::getPieceId, pieceId)
				.list();
		PieceScore score = new PieceScore(); 
		score.setObjectiveScore(BigDecimal.ZERO);
		score.setSubjectiveScore(BigDecimal.ZERO);
		score.setScore(BigDecimal.ZERO);
		for (PieceScore pieceScore : pieceScoreList) {
			if (pieceScore.getObjectiveScore() != null) {
				score.setObjectiveScore(score.getObjectiveScore().add(pieceScore.getObjectiveScore()));
			}
			if (pieceScore.getSubjectiveScore() != null) {
				score.setSubjectiveScore(score.getSubjectiveScore().add(pieceScore.getSubjectiveScore()));
			}
			if (pieceScore.getScore() != null) {
				score.setScore(score.getScore().add(pieceScore.getScore()));
			}
		}
		return score;
	}


	@Override
	public  CommentRecordVo selectCommentRecordVo(String projectId, String subjectId, String encodeId) {
		CommentRecordVo commentRecordVo = new CommentRecordVo();
		QueryWrapper<Task> taskWrapper = new QueryWrapper<>();
		taskWrapper.lambda().eq(Task :: getProjectId,projectId)
				.eq(Task :: getEncodeId,encodeId).eq(Task :: getSubjectId,subjectId);
		List<Task>  tasks =  taskMapper.selectList(taskWrapper);
		if(CollectionUtils.isEmpty(tasks)){
			return commentRecordVo;
		}
		QueryWrapper<PieceScore> pieceScoreWrapper = new QueryWrapper<>();
		pieceScoreWrapper.lambda().eq(PieceScore :: getPieceId,tasks.get(0).getPieceId())
				.eq(PieceScore :: getEncodeId,encodeId).eq(PieceScore :: getSubjectId,subjectId).orderByAsc(PieceScore :: getUpdateDate);
		List<PieceScore> pieceScores = pieceScoreMapper.selectList(pieceScoreWrapper);
		if(CollectionUtils.isEmpty(pieceScores)){
			return commentRecordVo;
		}
		//获取专家名称
		Set<String> userIds = pieceScores.stream().map(e -> e.getUserId()).collect(Collectors.toSet());
		QueryWrapper<ExamExpert> examExpertWrapper = new QueryWrapper<>();
		examExpertWrapper.lambda().eq(ExamExpert :: getProjectId,projectId).in(ExamExpert ::getExpertId,userIds);
		List<ExamExpert> examExperts = examExpertMapper.selectList(examExpertWrapper);
		Map<String,ExamExpert> examExpertMap = null;
		if(!CollectionUtils.isEmpty(examExperts)){
			examExpertMap = examExperts.stream().collect(Collectors.toMap(ExamExpert::getExpertId, ExamExpert -> ExamExpert,(key1 , key2)-> key2));
		}

		Set<String> pieceScoreIds = pieceScores.stream().map(e -> e.getId()).collect(Collectors.toSet());
		QueryWrapper<PieceScoreLog> pieceScoreLogWrapper = new QueryWrapper<>();
		pieceScoreLogWrapper.lambda().in(PieceScoreLog :: getPieceScoreId,pieceScoreIds);
		List<PieceScoreLog> pieceScoreLogs = pieceScoreLogMapper.selectList(pieceScoreLogWrapper);
		Map<String,List<PieceScoreLog>> pieceScoreLogMap = null;
		if(!CollectionUtils.isEmpty(pieceScoreLogs)){
			pieceScoreLogMap = pieceScoreLogs.stream().collect(Collectors.groupingBy(c -> c.getPieceScoreId()));
		}

		List<PipceScoreVo> pipceScoreVos = new ArrayList<>(pieceScores.size());
		for (PieceScore pieceScore :pieceScores) {
			PipceScoreVo pipceScoreVo = new PipceScoreVo();
			pipceScoreVo.setMarkEndTime(pieceScore.getMarkEndTime());
			pipceScoreVo.setMarkStartTime(pieceScore.getMarkStartTime());
			pipceScoreVo.setSubjectiveScore(pieceScore.getSubjectiveScore());
            pipceScoreVo.setStatus(CommonEnums.PIECCE_SCORE_FINSH_0.getCode());
            //缺席的也要显示成已完成
			if(null !=pieceScore.getSubjectiveScore() || (null != pieceScore.getFinish() && CommonEnums.PIECCE_SCORE_FINSH_1.getCode().equals(pieceScore.getFinish()))){
				pipceScoreVo.setStatus(pieceScore.getFinish());
			}
			if(!CollectionUtils.isEmpty(examExpertMap) && null != examExpertMap.get(pieceScore.getUserId())){
				pipceScoreVo.setExpertName(examExpertMap.get(pieceScore.getUserId()).getExpertName());
			}
			if(!CollectionUtils.isEmpty(pieceScoreLogMap) && !CollectionUtils.isEmpty(pieceScoreLogMap.get(pieceScore.getId()))){
				List<PieceScoreLog> scoreLogs = pieceScoreLogMap.get(pieceScore.getId()).stream().filter(s-> null != s.getUpdateDate()).collect(Collectors.toList());
				scoreLogs.sort(Comparator.comparing(PieceScoreLog::getUpdateDate));
				if(null != scoreLogs.get(0).getUpdateDate()){
					pipceScoreVo.setMarkEndTime(Date.from(scoreLogs.get(0).getUpdateDate().atZone( ZoneId.systemDefault()).toInstant()));
				}
				pipceScoreVo.setSubjectiveScore(scoreLogs.get(0).getSubjectiveScore());
				pipceScoreVo.setUpdateTime(pieceScore.getMarkEndTime());
			    pipceScoreVo.setLastSubjectiveScore(pieceScore.getSubjectiveScore());
				//只进行了一次评卷，需要赋值为null，前端不显示
				if(scoreLogs.size() == 1){
					pipceScoreVo.setUpdateTime(null);
					pipceScoreVo.setLastSubjectiveScore(null);
				}
			}
			pipceScoreVos.add(pipceScoreVo);
		}
		commentRecordVo.setPipceScoreVos(pipceScoreVos);
		//最终得分，需要判断考试是否完成
 		Set<Integer> markStatuss = tasks.stream().filter(e -> null != e.getMarkStatus()).map(e -> e.getMarkStatus()).collect(Collectors.toSet());
 		if(CollectionUtils.isEmpty(markStatuss)||markStatuss.contains(CommonEnums.TASK_MARK_STATUS_0.getCode())
				|| markStatuss.contains(CommonEnums.TASK_MARK_STATUS_1.getCode())){
			return commentRecordVo;
		}
		QueryWrapper<SubjectScore> subjectScoreWrapper = new QueryWrapper<>();
		subjectScoreWrapper.lambda().eq(SubjectScore :: getProjectId,projectId)
				.eq(SubjectScore ::getSubjectId,subjectId).eq(SubjectScore :: getEncodeId,encodeId).last("limit 1");
		SubjectScore subjectScore= subjectScoreMapper.selectOne(subjectScoreWrapper);
		if(null != subjectScore){
			commentRecordVo.setScore(subjectScore.getSubjectiveScore());
			commentRecordVo.setMarkEndTime(subjectScore.getUpdateDate());
		}
		return commentRecordVo;
	}

	@Override
	public List<OptionItemVo> getExpertSubject(String projectId, String officeId) {
		return this.baseMapper.getExpertSubject(projectId, officeId);
	}

	@Override
	public List<OptionItemVo> getExpertPlace(String projectId, String officeId) {
		return this.baseMapper.getExpertPlace(projectId, officeId);
	}

	@Override
	public PieceScore selectPieceScoreBySubjectIdAndTaskIdAndEncodeIdAndUserId(String subjectId, String pieceId, String taskId, String encodeId, String userId) {
		return pieceScoreMapper.getByPieceIdAndTaskIdAndEncodeId( subjectId,  pieceId,  taskId,  encodeId,  userId);
	}

	@Override
	public List<PieceScore> selectPieceScoreByTaskId(String taskId, String userId) {
		return pieceScoreMapper.getPieceScoreByTaskId(taskId, userId);
	}

	@Override
	public PieceScore selectPieceScoreByTaskIdLimitOne(String taskId) {
		return pieceScoreMapper.selectPieceScoreByTaskIdLimitOne(taskId);
	}

	
}
